﻿using BigFileUploadDemo4Framework.Lib;
using BigFileUploadDemo4Framework.RRModels;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;

namespace BigFileUploadDemo4Framework.Controllers
{
    [RoutePrefix("Api/File")]
    public class FileController : ApiController
    {
        private readonly string _baseUploadDir = $"{System.Web.HttpContext.Current.Request.PhysicalApplicationPath}\\wwwroot\\upfile\\";

        /// <summary>
        /// web页面上传文件
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns> 
        [HttpPost, Route("UploadWeb")]
        public UploadResponseModel UploadWeb()
        {
            var uploadResponseModel = new RRModels.UploadResponseModel();
            try
            {
                var fileName = System.Web.HttpContext.Current.Request.Form["file_name"];
                //当前分块序号
                var index = Convert.ToInt32(System.Web.HttpContext.Current.Request.Form["file_index"]);
                //所有块数
                var maxChunk = Convert.ToInt32(System.Web.HttpContext.Current.Request.Form["file_total"]);
                //前端传来的md5值
                var md5 = System.Web.HttpContext.Current.Request.Form["file_md5"];
                //临时保存分块的目录
                var dir = Path.Combine(_baseUploadDir, md5);
                if (!Directory.Exists(dir))
                    Directory.CreateDirectory(dir);
                //分块文件名为索引名，更严谨一些可以加上是否存在的判断，防止多线程时并发冲突
                var filePath = Path.Combine(dir, index.ToString());
                //表单中取得分块文件
                var file = System.Web.HttpContext.Current.Request.Files["file_data"];
                //文件扩展名
                var suffix = System.Web.HttpContext.Current.Request.Form["file_suffix"];
                //var filePathWithFileName = string.Concat(filePath, fileName);
                var filePathWithFileName = string.Concat(filePath, "." + suffix);
                using (var stream = new FileStream(filePathWithFileName, FileMode.Create))
                {
                    //file.CopyToAsync(stream);
                    file.InputStream.CopyTo(stream);
                    LogicLog.WriteLogicLog(index.ToString(), _baseUploadDir + md5 + ".txt", false);
                }
                
                uploadResponseModel.file_index = index;
                //如果是最后一个分块， 则合并文件
                if (index == maxChunk)
                {
                    FileLib fi = new FileLib();
                    uploadResponseModel = fi.MergeFileForWeb(fileName, md5, _baseUploadDir);
                    uploadResponseModel.Completed = true;
                }
                return uploadResponseModel;//直接返回符合前端数据结构的对象，和resp结构不同，偷个小懒；
            }
            catch (Exception ex)
            {
                LogicLog.WriteLogicLog($"{ex.Message},{ex.StackTrace}", "");
            }
            return uploadResponseModel;
        }

        /// <summary>
        /// 验证文件上传情况
        /// </summary>
        /// <returns></returns>
        [HttpPost, Route("CheckFile")]
        public Response CheckFile()
        {
            Response resp = new Response();
            //前端传来的md5值
            var file_name = System.Web.HttpContext.Current.Request.Form["file_name"];
            var md5 = System.Web.HttpContext.Current.Request.Form["file_md5"];
            var maxChunk = Convert.ToInt32(System.Web.HttpContext.Current.Request.Form["file_total"]);
            string logPath = _baseUploadDir + md5 + ".txt";
            var logs = LogicLog.ReadLogicLog(logPath);
            if (logs != null)
            {
                int shards = logs.Count();
                if (shards >= Convert.ToInt32(maxChunk))
                {
                    resp.code = 2;
                    resp.message = "该文件已上传";
                    resp.data = new { url = $"/upfile/{DateTime.Now.ToString("yyyyMM")}/{md5}/{file_name}" };
                }
                else
                {
                    resp.code = 0;
                    resp.message = $"该文件已上传步长{shards}/{maxChunk}，继续上传";
                    resp.data = new { file_index = shards - 1, percent = Convert.ToDouble(shards) / Convert.ToDouble(maxChunk) * 100 };
                }
                //存在日志，文件却找不着了，说明被删了,注意排除掉临时文件夹的情况  
                string file_path = $"{_baseUploadDir}\\{DateTime.Now.ToString("yyyyMM")}\\{md5}\\{file_name}";
                string tmp_path = $"{_baseUploadDir}\\{md5}";
                if (!System.IO.Directory.Exists(tmp_path) && !System.IO.File.Exists(file_path) && System.IO.File.Exists(logPath))
                {
                    System.IO.File.Delete(logPath);
                    resp.code = 0;
                    resp.message = "该文件已被删除";
                    return resp;
                }
            }
            return resp;
        }

        [HttpGet,Route("test")]
        public Response Test()
        {
            Response resp = new Response();
            return resp;
        }
    }
}
